﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Globalization;
using System.Linq;
using EstateNuke.Data.Properties;

namespace EstateNuke.Data
{
    public partial class Cancellation
    {
        #region Fileds & Properties

        /// <summary>
        /// </summary>
        internal IList<CancellationWithdrawalReason> CancellationWithdrawalReasons
        {
            get
            {
                return InternalCancellationWithdrawalReasons.Where(cancellationWithdrawalReason => cancellationWithdrawalReason.IsDeleted == false).ToList();
            }
        }

        /// <summary>
        /// </summary>
        public IList<WithdrawalReason> WithdrawalReasons
        {
            get
            {
                return InternalCancellationWithdrawalReasons.Where(cancellationWithdrawalReason => cancellationWithdrawalReason.IsDeleted == false && cancellationWithdrawalReason.WithdrawalReason.IsDeleted == false).Select(cancellationWithdrawalReason => cancellationWithdrawalReason.WithdrawalReason).ToList();
            }
        }

        #endregion

        #region Add & Remove CancellationWithdrawalReason

        /// <summary>
        /// </summary>
        /// <returns></returns>
        internal CancellationWithdrawalReason AddCancellationWithdrawalReason(User modifiedUser)
        {
            if (modifiedUser == null)
            {
                throw new ArgumentNullException("modifiedUser");
            }
            var cancellationWithdrawalReason = new CancellationWithdrawalReason
                                                   {
                                                       RowId = Guid.NewGuid(),
                                                       CreatedDate = DateTime.Now,
                                                   };
            InternalCancellationWithdrawalReasons.Add(cancellationWithdrawalReason);
            cancellationWithdrawalReason.IsDeleted = false;
            cancellationWithdrawalReason.ModifiedDate = DateTime.Now;
            cancellationWithdrawalReason.ModifiedByUser = modifiedUser;
            return cancellationWithdrawalReason;
        }

        /// <summary>
        /// </summary>
        /// <param name = "cancellationWithdrawalReason"></param>
        /// <param name = "modifiedUser"></param>
        internal void RemoveCancellationWithdrawalReason(CancellationWithdrawalReason cancellationWithdrawalReason, User modifiedUser)
        {
            if (cancellationWithdrawalReason == null)
            {
                throw new ArgumentNullException("cancellationWithdrawalReason");
            }
            if (modifiedUser == null)
            {
                throw new ArgumentNullException("modifiedUser");
            }
            if (InternalCancellationWithdrawalReasons.Contains(cancellationWithdrawalReason))
            {
                cancellationWithdrawalReason.Delete(modifiedUser);
            }
        }

        #endregion

        #region Set WithdrawalReasons

        /// <summary>
        /// </summary>
        /// <param name = "withdrawalReasons"></param>
        /// <param name = "modifiedUser"></param>
        public void SetWithdrawalReasons(IList<WithdrawalReason> withdrawalReasons, User modifiedUser)
        {
            if (modifiedUser == null)
            {
                throw new ArgumentNullException("modifiedUser");
            }
            if (withdrawalReasons != null)
            {
                var cancellationWithdrawalReasons = InternalCancellationWithdrawalReasons.ToList();
                cancellationWithdrawalReasons.ForEach(cancellationWithdrawalReason => cancellationWithdrawalReason.Delete(modifiedUser));
                foreach (var withdrawalReason in withdrawalReasons.Distinct())
                {
                    var currentCancellationWithdrawalReason = cancellationWithdrawalReasons.FirstOrDefault(cancellationWithdrawalReason => cancellationWithdrawalReason.WithdrawalReason == withdrawalReason);
                    if (currentCancellationWithdrawalReason != null)
                    {
                        currentCancellationWithdrawalReason.CancelDelete(modifiedUser);
                    }
                    else
                    {
                        currentCancellationWithdrawalReason = AddCancellationWithdrawalReason(modifiedUser);
                        currentCancellationWithdrawalReason.WithdrawalReason = withdrawalReason;
                    }
                }
            }
        }

        #endregion

        #region Ensure

        /// <summary>
        /// </summary>
        public void Ensure()
        {
            if (DeductibleAmount < 0)
            {
                throw new EntityException(string.Format(CultureInfo.CurrentCulture, Resources.NonNegativeNumberAllowed, RowId, "Cancellation", "DeductibleAmount"));
            }
            Comment = string.IsNullOrEmpty(Comment) ? null : Comment.Length > 512 ? Comment.Substring(0, 512) : Comment;
        }

        #endregion

        #region Delete

        /// <summary>
        /// </summary>
        public void Delete(User modifiedUser)
        {
            if (modifiedUser == null)
            {
                throw new ArgumentNullException("modifiedUser");
            }
            IsDeleted = true;
            ModifiedDate = DateTime.Now;
            ModifiedByUser = modifiedUser;
            ((List<CancellationWithdrawalReason>) CancellationWithdrawalReasons).ForEach(cancellationWithdrawalReason => cancellationWithdrawalReason.Delete(modifiedUser));
        }

        /// <summary>
        /// </summary>
        public void CancelDelete(User modifiedUser)
        {
            if (modifiedUser == null)
            {
                throw new ArgumentNullException("modifiedUser");
            }
            IsDeleted = false;
            ModifiedDate = DateTime.Now;
            ModifiedByUser = modifiedUser;
        }

        #endregion
    }
}